package net.lab1024.sa.admin.module.business.category.service;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.common.DateTimeUtils;
import net.lab1024.sa.admin.common.EnumConverter;
import net.lab1024.sa.admin.common.Log;
import net.lab1024.sa.admin.config.*;
import net.lab1024.sa.admin.module.business.category.dao.RecordDetailMapper;
import net.lab1024.sa.admin.module.business.category.dao.SynthesisRecordMapper;
import net.lab1024.sa.admin.module.business.category.dao.UserDao;
import net.lab1024.sa.admin.module.business.category.domain.dto.RecordQueryDTO;
import net.lab1024.sa.admin.module.business.category.domain.dto.UserDTO;
import net.lab1024.sa.admin.module.business.category.domain.entity.*;
import net.lab1024.sa.admin.module.business.category.domain.vo.SynthesisRecordVO;
import net.lab1024.sa.base.common.exception.BusinessException;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class SynthesisRecordService {
    private final SynthesisRecordMapper recordMapper;
    private final RecordDetailMapper detailMapper;
    private final PythonServiceClient pythonClient;
    @Autowired
    UserDao userDao;

    public Page<SynthesisRecordVO> listRecords(RecordQueryDTO query) {
        Page<SynthesisRecord> pageInfo = Page.of(query.getPage(), query.getSize());
        LambdaQueryWrapper<SynthesisRecord> queryWrapper = buildQueryWrapper(query);

        Page<SynthesisRecord> page = recordMapper.selectPage(pageInfo, queryWrapper);
        List<SynthesisRecord> recordList = page.getRecords();

        if (CollectionUtils.isEmpty(recordList)) {
            return new Page<>(); // 返回一个空的 Page 对象
        }

        // 转换 SynthesisRecord 列表为 SynthesisRecordVO 列表
        List<SynthesisRecordVO> synthesisRecordVOList = recordList.stream()
                .map(synthesisRecord -> {
                    SynthesisRecordVO synthesisRecordVO = new SynthesisRecordVO();
                    BeanUtils.copyProperties(synthesisRecord, synthesisRecordVO);
                    LocalDateTime localDateTime = synthesisRecord.getCreateTime();
                    String strDateTime = DateTimeUtils.getStrDateTime(localDateTime);
                    synthesisRecordVO.setStrCreateTime(strDateTime);
                    localDateTime = synthesisRecord.getUpdateTime();
                    strDateTime = DateTimeUtils.getStrDateTime(localDateTime);
                    synthesisRecordVO.setStrUpdateTime(strDateTime);
                    return synthesisRecordVO;
                })
                .collect(Collectors.toList());

        // 创建一个新的 Page 对象来包装转换后的 VO 列表
        Page<SynthesisRecordVO> resultPage = new Page<>();
        resultPage.setRecords(synthesisRecordVOList);
        resultPage.setTotal(page.getTotal());
        resultPage.setCurrent(page.getCurrent());
        resultPage.setSize(page.getSize());

        return resultPage;
    }

    public RetroResponse.RetroResult2 analyze(SynthesisRequest request) {

        // 1. 验证输入
        validateSynthesisRequest(request);

        // 2. 调用Python微服务
        RetroResponse.RetroResult2 result = pythonClient.performRetrosynthesis(request);

        // 3. 检查错误
        // if (result.getError() != null) {
        //     throw new SynthesisException("Python服务返回错误: " + result.getError());
        // }

        return result;
    }

    private void validateSynthesisRequest(SynthesisRequest synthesisRequest) {
        String smiles = synthesisRequest.getSmiles();
        if (smiles == null || smiles.trim().isEmpty()) {
            throw new IllegalArgumentException("SMILES 字符串不能为空");
        }
        String databaseName = synthesisRequest.getDatabaseName();
        if (databaseName == null || databaseName.trim().isEmpty()) {
            throw new IllegalArgumentException("databaseName 字符串不能为空");
        }
        String modelName = synthesisRequest.getModelName();
        if (modelName == null || modelName.trim().isEmpty()) {
            throw new IllegalArgumentException("modelName 字符串不能为空");
        }
    }

    private List<SynthesisRecord> convertSynthesisRecordList(List<SynthesisRecord> synthesisRecordList) {
        try {
            return synthesisRecordList.stream().map(synthesisRecord -> {
                SynthesisRecord vo = new SynthesisRecord();
                BeanUtils.copyProperties(synthesisRecord, vo);
                // 转换枚举值为显示名称
                String result = DateTimeUtils.getStrDateTime(vo.getCreateTime());
                vo.setStrCreateTime(result);
                result = DateTimeUtils.getStrDateTime(vo.getUpdateTime());
                vo.setStrUpdateTime(result);
                // 其他字段转换...
                return vo;
            }).collect(Collectors.toList());

        } catch (Exception e) {
            log.error("转化 UserVO 异常", e);
            return null;
        }
    }

    public List<SynthesisRecordVO> listAllRecords(RecordQueryDTO query) {
        LambdaQueryWrapper<SynthesisRecord> queryWrapper = buildQueryWrapper(query);
        List<SynthesisRecord> synthesisRecordList = recordMapper.selectList(queryWrapper);
        synthesisRecordList = convertSynthesisRecordList(synthesisRecordList);
        if (CollectionUtils.isEmpty(synthesisRecordList)) {
            return null;
        }
        List<SynthesisRecordVO> synthesisRecordVOList = synthesisRecordList.stream().map(synthesisRecord -> {
            SynthesisRecordVO synthesisRecordVO = new SynthesisRecordVO();
            BeanUtils.copyProperties(synthesisRecord, synthesisRecordVO);
            return synthesisRecordVO;
        }).collect(Collectors.toList());
        return synthesisRecordVOList;
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<SynthesisRecord> buildQueryWrapper(RecordQueryDTO query) {
        LambdaQueryWrapper<SynthesisRecord> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.like(StringUtils.isNotBlank(query.getChemicalName()),
                SynthesisRecord::getChemicalName, query.getChemicalName())
                .ge(query.getStartTime() != null, SynthesisRecord::getCreateTime, query.getStartTime())
                .le(query.getEndTime() != null, SynthesisRecord::getCreateTime, query.getEndTime())
                .orderByDesc(SynthesisRecord::getUpdateTime);

        Long loginUserId = SmartRequestUtil.getRequestLoginUserId();
        User user = userDao.selectById(loginUserId);

        if (EnumConverter.generalUserRoleCode.equals(user.getRole())) {
            queryWrapper.eq(true,
                    SynthesisRecord::getCreatorId, user.getUserCode());
        } else {
            queryWrapper.like(StringUtils.isNotBlank(query.getCreatorName()),
                    SynthesisRecord::getCreatorName, query.getCreatorName());
        }

        return queryWrapper;
    }

    public SynthesisRecordVO getRecordById(Long id) {
        SynthesisRecordVO synthesisRecordVO = new SynthesisRecordVO();
        SynthesisRecord synthesisRecord = getSynthesisRecordById(id);
        if (null == synthesisRecord) {
            log.info(String.format("id为%s 的逆合成记录不存在", id));
            return null;
        }
        BeanUtils.copyProperties(synthesisRecord, synthesisRecordVO);
        RetroResult2 retroResult2 = string2RetroResult2(synthesisRecord.getResultJson());
        synthesisRecordVO.setRetroResult2(retroResult2);
        return synthesisRecordVO;
    }

    private RetroResult2 string2RetroResult2(String resultJson) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            RetroResult2 retroResult2 = objectMapper.readValue(resultJson, RetroResult2.class);
            return retroResult2;
        } catch (Exception e) {
            log.error("string2RetroResult2 异常", e);
            return null;
        }
    }

    public SynthesisRecord getSynthesisRecordById(Long id) {
        SynthesisRecord record = recordMapper.selectById(id);
        // if (record == null) {
        //     throw new BusinessException("记录不存在");
        // }

        // 加载关联的明细
        // LambdaQueryWrapper<RecordDetail> detailQuery = new LambdaQueryWrapper<>();
        // detailQuery.eq(RecordDetail::getRecordId, id)
        //         .orderByAsc(RecordDetail::getStep);
        //List<RecordDetail> details = detailMapper.selectList(detailQuery);
        //record.setDetails(details);

        return record;
    }

    @Log(module = "记录管理", operation = "新增合成记录")
    @Transactional(rollbackFor = Exception.class)
    public Long createRecord(SynthesisRecord record) {
        try {
            // 1. 调用Python服务（可能失败点）
            if (null == record.getRetroResult2()) {
                SynthesisRequest synthesisRequest = new SynthesisRequest(record.getTargetSmiles(), record.getDatabaseName(), record.getModelName());
                RetroResponse.RetroResult2 retroResult = pythonClient.performRetrosynthesis(synthesisRequest);
                record.setResultJson(retroResult.toString());
            } else {
                record.setResultJson(record.getRetroResult2().toString());
            }


            UserContext userContext = UserContextHolder.getUserContext();
            record.setCreatorName(userContext.getUsername());
            record.setCreatorId(userContext.getUserCode());

            // 2. 插入主记录（关键操作）
            int insertResult = recordMapper.insert(record);
            if (insertResult != 1) {
                log.error("主记录插入失败，影响行数: {}", insertResult);
                throw new DataCreationException("主记录创建失败");
            }

            // 3. 插入明细（可选但需保证完整性）
            //if (record.getDetails() != null && !record.getDetails().isEmpty()) {

            //    record.getDetails().forEach(detail -> detail.setRecordId(record.getId()));
            //    int insertCount = detailMapper.insertBatch(record.getDetails());
            //    if (insertCount != record.getDetails().size()) {
            //        log.error("明细插入不完整，预期:{} 实际:{}",
            //                record.getDetails().size(), insertCount);
            //        throw new DataIntegrityViolationException("明细插入不完整");
            //    }

            //    log.debug("成功插入{}条明细", insertCount);
            //}

            return record.getId();

        } catch (ServiceException e) {
            throw e; // 已处理的业务异常直接抛出
        } catch (Exception e) {
            log.error("记录创建失败: {}", e.getMessage());
            throw new ServiceException("SYNTHESIS_CREATE_FAILED", "记录创建失败", e);
        }
    }

    @Log(module = "记录管理", operation = "编辑合成记录")
    @Transactional(rollbackFor = Exception.class)  // 明确指定所有异常都回滚
    public boolean updateRecord(SynthesisRecord record) {
        //try {
        validateUpdateParam(record);
        record.setResultJson(record.getRetroResult2().toString());
        SynthesisRecord synthesisRecord = getSynthesisRecordById(record.getId());
        Assert.isFalse(null == synthesisRecord, "逆合成记录id不存在");
        if (null != synthesisRecord) {
            record.setCreatorId(synthesisRecord.getCreatorId());
            record.setCreatorName(synthesisRecord.getCreatorName());
            record.setCreateTime(synthesisRecord.getCreateTime());
        }
        // 目标分子改变时重新分析
        // if (!existing.getTargetSmiles().equals(record.getTargetSmiles())) {
        //     RetroResult2 retroResult = pythonClient.performRetrosynthesis(record.getTargetSmiles());
        //     //TODO
        //     //record.setResultJson(retroResult.getPaths());
        // }

        // 1. 更新主记录
        int updateRecordResult = recordMapper.updateById(record);
        if (updateRecordResult != 1) {
            log.warn("主记录更新失败，预期更新1条，实际更新{}条", updateRecordResult);
            return false;
        }

        // 2. 删除旧明细
        // LambdaQueryWrapper<RecordDetail> wrapper = new LambdaQueryWrapper<>();
        // wrapper.eq(RecordDetail::getRecordId, record.getId());
        // int deleteCount = detailMapper.delete(wrapper);
        // log.debug("删除{}条旧明细", deleteCount);
        // // 3. 插入新明细
        // int insertCount = 0;
        // if (record.getDetails() != null && !record.getDetails().isEmpty()) {
        //     record.getDetails().forEach(detail -> detail.setRecordId(record.getId()));
        //     insertCount = detailMapper.insertBatch(record.getDetails());
        //
        //     if (insertCount != record.getDetails().size()) {
        //         log.error("明细插入数量不匹配，预期:{}，实际:{}",
        //                 record.getDetails().size(), insertCount);
        //         throw new DataIntegrityViolationException("明细插入不完整");
        //     }
        // }

        log.info("更新主记录{}条", updateRecordResult);
        //log.info("更新主记录{}条，明细{}条", updateRecordResult, insertCount);
        return true;

        //} catch (Exception e) {
        //    log.error("记录更新失败: {}", e.getMessage());
        //    throw new ServiceException("SYNTHESIS_UPDATE_FAILED", "记录更新失败", e);  // 触发事务回滚
        //}
    }

    private void validateUpdateParam(SynthesisRecord record) {
        Assert.isFalse(null == record, "入参为空");
        Assert.isFalse(null == record.getId(), "逆合成记录id为空");
    }

    @Log(module = "记录管理", operation = "删除合成记录")
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRecord(Long id) {
        try {
            // 1. 检查记录是否存在
            SynthesisRecord record = recordMapper.selectById(id);
            if (record == null) {
                log.warn("删除失败，记录不存在: {}", id);
                return false;
            }

            // 2. 删除关联明细
            // LambdaQueryWrapper<RecordDetail> wrapper = new LambdaQueryWrapper<>();
            // wrapper.eq(RecordDetail::getRecordId, id);
            // int deleteDetails = detailMapper.delete(wrapper);
            // log.debug("删除{}条关联明细", deleteDetails);

            // 3. 删除主记录（关键操作）
            int deleteResult = recordMapper.deleteById(id);
            if (deleteResult != 1) {
                log.error("主记录删除失败，影响行数: {}", deleteResult);
                throw new DataDeletionException("主记录删除失败");
            }

            return true;

        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("记录删除失败: {}", e.getMessage());
            throw new ServiceException("SYNTHESIS_DELETE_FAILED", "记录删除失败", e);
        }
    }

}